package com.zkingsoft.actions.common;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import com.zkingsoft.anotations.RemoveRequestToken;
import com.zkingsoft.anotations.SaveRequestToken;
import com.zkingsoft.authority.Matrix;
import com.zkingsoft.authority.loginStrategy.AccountPasswordLogin;
import com.zkingsoft.authority.loginStrategy.LoginStrategy;
import com.zkingsoft.constance.SystemConstance;
import com.zkingsoft.constraint.BaseController;
import com.zkingsoft.exception.GlobleException;
import com.zkingsoft.model.distribution.DisDesigner;
import com.zkingsoft.model.distribution.DisDesignerWorks;
import com.zkingsoft.model.sys.SysUsers;
import com.zkingsoft.pojo.AjaxResult;
import com.zkingsoft.pojo.PaginationVO;
import com.zkingsoft.services.distribution.DisDesignerService;
import com.zkingsoft.services.distribution.DisDesignerWorksService;
import com.zkingsoft.services.sys.SysUsersService;
import com.zkingsoft.util.EncrypUtil;
import com.zkingsoft.util.StringUtils;
import com.zkingsoft.util.WebUtil;

/**
 * @description 通用控制器,本action未经session过验证器
 * @author 姜友瑶
 * @email 935090232@qq.com
 * @date 2016-06-26
 */
@RequestMapping(value = "/common")
@Controller
public class CommonController extends BaseController {

	@Resource
	SysUsersService sysUsersService;

	@Resource
	Matrix matrix;

	@Resource
	private DisDesignerService userService;

	@Resource
	private DisDesignerWorksService disDesignerWorksService;

	/**
	 * @Description: 页面定向方法，每个权限模块公用一个，每个模块共享一个一级路径，已便于进行权限过滤
	 * @date 2016年8月30日
	 */
	@RequestMapping(value = "/redirect/{page1}/{page2}")
	public String redirect(@PathVariable("page1") String page1,
			@PathVariable("page2") String page2) {
		return "common/" + page1 + "/" + page2;
	}

	/**
	 * 
	 * @Description: 页面定向方法，每个权限模块公用一个，每个模块共享一个一级路径，已便于进行权限过滤
	 * @date 2016年8月30日
	 */
	@RequestMapping(value = "/redirect/{page1}")
	public String redirect(@PathVariable("page1") String page1) {
		return "common/" + page1;
	}

	/**
	 * 
	 * @Description: 登录验证
	 * @author:姜友瑶
	 * @param user
	 * @param request
	 * @return 返回类型 AjaxResult
	 * @date 2016年8月30日
	 */
	@RequestMapping(value = "/dologin")
	public @ResponseBody AjaxResult dologin(SysUsers user) {

		LoginStrategy apLogin = new AccountPasswordLogin(user, sysUsersService);
		user = matrix.login(apLogin);

		switch (user.getSuUserType()) {
		case SystemConstance.USER_TYPE_DEVELOPER:// 开发人员
			return new AjaxResult(AjaxResult.STATUS_OK,
					"developer/redirect/index", null);
		case SystemConstance.USER_TYPE_SUPER:// 超级管理员
			return new AjaxResult(AjaxResult.STATUS_OK, "super/redirect/index",
					null);
		case SystemConstance.USER_TYPE_ADMIN:// 企业管理员
			return new AjaxResult(AjaxResult.STATUS_OK, "admin/redirect/index",
					null);
		case SystemConstance.USER_TYPE_EMPLOYEE:// 企业用户
			return new AjaxResult(AjaxResult.STATUS_OK, "admin/redirect/index",
					null);
		case SystemConstance.USER_TYPE_CUSTIMER:// 普通用户
			return new AjaxResult(AjaxResult.STATUS_OK, "admin/redirect/index",
					null);
		default:// 不能识别的用户
			return new AjaxResult(AjaxResult.STATUS_ERR,
					"common/redirect/login", "什么鬼！");
		}
	}

	/**
	 * 
	 * @Description: 开发模式登录
	 * @author:姜友瑶
	 * @param user
	 * @return 返回类型 AjaxResult
	 * @date 2016年11月15日
	 */
	@RequestMapping(value = "/debugLogin")
	public String debugLogin() {
		SysUsers user = new SysUsers();
		user.setSuAccount("admin");
		user.setSuPassword("123");
		LoginStrategy apLogin = new AccountPasswordLogin(user, sysUsersService);
		matrix.login(apLogin);
		return "admin/index";
	}

	/**
	 * 
	 * @Description: 用户退出系统
	 * @author:姜友瑶
	 * @return
	 * @throws Exception
	 *             返回类型 String
	 * @date 2016年11月15日
	 */
	@RequestMapping(value = "/loginOut")
	public String loginOut() throws Exception {
		matrix.getLoginOut();
		return "redirect:/common/redirect/login";
	}

	@RequestMapping(value = "/doDesignerLogin")
	@ResponseBody
	public AjaxResult doDesignerLogin(String desAccount, String desPassword) {
		DisDesigner disDesigner = new DisDesigner();
		// 加密密码
		try {
			disDesigner.setDesPassword(EncrypUtil.getMD5(desPassword));
		} catch (UnsupportedEncodingException e) {
			throw new GlobleException("登录失败！");
		}
		disDesigner.setDesAccount(desAccount);
		List<DisDesigner> list = userService.findByModel(disDesigner);
		if (list == null || list.isEmpty()) {
			throw new GlobleException("帐号或密码错误！");
		}
		disDesigner = list.get(0);
		if (!"2".equals(disDesigner.getDesAuditStatus())) {
			throw new GlobleException("帐号待审核！");
		}
		WebUtil.setSessionAttribute(SystemConstance.APP_LOGIN_KEY, disDesigner);
		AjaxResult result = new AjaxResult(AjaxResult.STATUS_OK,
				"common/designerIndex", "登录成功！");
		return result;
	}

	@RequestMapping(value = "/designerIndex")
	public String designerIndex() throws Exception {
		DisDesigner appLoginUser = (DisDesigner) WebUtil
				.getSessionAttribute(SystemConstance.APP_LOGIN_KEY);
		if (appLoginUser == null) {
			return "common/designerLogin";
		}
		return "common/designerIndex";
	}

	/**
	 * 列表显示
	 */
	@RequestMapping(value = "/showMyWorks")
	public @ResponseBody AjaxResult showMyWorks(
			DisDesignerWorks disDesignerWorks, PaginationVO pageVo) {
		DisDesigner appLoginUser = (DisDesigner) WebUtil
				.getSessionAttribute(SystemConstance.APP_LOGIN_KEY);
		if (appLoginUser == null) {
			return new AjaxResult(AjaxResult.STATUS_ERR, null, "登录失效，请重新登录！");
		}
		disDesignerWorks.setDesId(appLoginUser.getDesId());

		return showList(disDesignerWorksService, disDesignerWorks, pageVo);
	}

	/**
	 * 删除
	 */
	@RequestMapping(value = "/delMyWorks")
	public @ResponseBody AjaxResult delMyWorks(String keys) {
		DisDesigner appLoginUser = (DisDesigner) WebUtil
				.getSessionAttribute(SystemConstance.APP_LOGIN_KEY);
		if (appLoginUser == null) {
			return new AjaxResult(AjaxResult.STATUS_ERR, null, "登录失效，请重新登录！");
		}
		int i = 0;
		List<Long> ids = StringUtils.strToCollToLong(keys, ",");
		for (Long id : ids) {
			DisDesignerWorks disDesignerWorks = disDesignerWorksService
					.findById(id);
			if (disDesignerWorks.getDesId() == appLoginUser.getDesId()) {
				i += disDesignerWorksService.removeById(disDesignerWorks
						.getWorkId());
			}
		}
		if (i > 0) {
			return new AjaxResult(AjaxResult.STATUS_OK, null, "成功删除" + i
					+ "条数据");
		} else {
			return new AjaxResult(AjaxResult.STATUS_ERR, null, "删除失败");
		}
	}

	// 记录编辑前的值Before_Edit_Value
	public static final String BEV = "DisDesignerWorks_BEV";

	/**
	 * 进入修改界面
	 */
	@SaveRequestToken
	@RequestMapping(value = "/editMyWork")
	public String editMyWork(Long id) {
		DisDesignerWorks disDesignerWorks;
		if (id != null) {
			disDesignerWorks = disDesignerWorksService.findById(id);
			WebUtil.getRequest().setAttribute("obj", disDesignerWorks);
			WebUtil.setSessionAttribute(BEV, disDesignerWorks);
		}
		return "common/designerForm";
	}

	/**
	 * 新增或者修改页面
	 */
	@RemoveRequestToken
	@RequestMapping(value = "/addOrModifyMyWork")
	public @ResponseBody AjaxResult addOrModifyMyWork(
			DisDesignerWorks disDesignerWorks) {
		DisDesigner appLoginUser = (DisDesigner) WebUtil
				.getSessionAttribute(SystemConstance.APP_LOGIN_KEY);
		if (appLoginUser == null) {
			return new AjaxResult(AjaxResult.STATUS_ERR, null, "登录失效，请重新登录！");
		}

		if (disDesignerWorks.getWorkId() != null) {
			disDesignerWorks.setWorkId(((DisDesignerWorks) WebUtil
					.getSessionAttribute(BEV)).getWorkId());
			AjaxResult result = modify(disDesignerWorksService,
					WebUtil.getSessionAttribute(BEV), disDesignerWorks, "作品");
			WebUtil.removeSessionAttribute(BEV);
			return result;
		} else {
			disDesignerWorks.setDesId(appLoginUser.getDesId());
			disDesignerWorks.setWorkCreateTime(new Date());
			disDesignerWorks.setWorkViewTimes(0);
			return add(disDesignerWorksService, disDesignerWorks, "作品");
		}
	}

	Logger log = Logger.getLogger(CommonController.class);
	
	@Value("${file_storage_path}")
	private String fileStoragePath;
	@Value("${nginx_url}")
	private String nginxUrl;
	// 最大文件大小
	private long maxSize = 1024 * 1024 * 5;
	private String fileTypeImg = "image";
	// 定义文件上传类型
	public static HashMap<String, String> extMap = new HashMap<String, String>();
	static {
		extMap.put("image", "gif,jpg,jpeg,png,bmp");
		extMap.put("flash", "swf,flv");
		extMap.put("media", "swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb");
		extMap.put("file",
				"doc,docx,xls,xlsx,ppt,htm,html,txt,zip,rar,gz,bz2,pdf");
	}

	/**
	 * 多文件上传
	 * 
	 * @author maoluguang
	 * @throws IOException
	 */
	@RequestMapping(value = "/doMultiUpload")
	public String doMultiUpload(HttpServletResponse response,
			MultipartHttpServletRequest request) throws IOException {

		// 文件保存目录路径
		String savePath = fileStoragePath;
		// 文件保存目录URL
		String saveUrl = nginxUrl;
		String msgPag = "common/fileUploadResult";

		response.setContentType("text/html; charset=UTF-8");
		request.setCharacterEncoding("UTF-8");

		// 保存和访问路径检查
		if (StringUtils.isBlank(saveUrl) || StringUtils.isBlank(savePath)) {
			request.setAttribute("status", "err");
			request.setAttribute("msg", "文件上传失败错误代码：001");
			return msgPag;
		}
		// 检查目录
		File uploadDir = new File(savePath);
		if (!uploadDir.isDirectory()) {
			uploadDir.mkdir();
		}
		// 检查目录写权限
		if (!uploadDir.canWrite()) {
			request.setAttribute("status", "err");
			request.setAttribute("msg", "上传目录没有写权限");
			return msgPag;
		}

		// 创建文件夹
		savePath += fileTypeImg + "/";
		saveUrl += fileTypeImg + "/";
		File saveDirFile = new File(savePath);
		if (!saveDirFile.exists()) {
			saveDirFile.mkdirs();
		}
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
		String ymd = sdf.format(new Date());
		savePath += ymd + "/";
		saveUrl += ymd + "/";
		File dirFile = new File(savePath);
		if (!dirFile.exists()) {
			dirFile.mkdirs();
		}

		StringBuilder visitPaths = new StringBuilder();
		// 取得request中的所有文件名
		Iterator<String> fileNames = request.getFileNames();
		while (fileNames.hasNext()) {
			List<MultipartFile> files = request.getFiles(fileNames.next());

			for (MultipartFile file : files) {
				log.info("上传文件名：" + file.getOriginalFilename());
				log.info("上传文件大小：" + file.getBytes().length);
				if (file.getBytes().length > maxSize) {
					request.setAttribute("status", "err");
					request.setAttribute("msg", "上传文件大小超过限制");
					return msgPag;
				}
				String fileName = file.getOriginalFilename();
				String fileExt = fileName.substring(
						fileName.lastIndexOf(".") + 1).toLowerCase();
				if (!Arrays.<String> asList(extMap.get(fileTypeImg).split(","))
						.contains(fileExt)) {
					request.setAttribute("status", "err");
					request.setAttribute("msg", "上传文件扩展名是不允许的扩展名。\n只允许"
							+ extMap.get(fileTypeImg) + "格式。");
					return msgPag;
				}
				fileName = fileName.replace("." + fileExt, "");
				fileName = getSensitive(fileName);
				String newFileName = fileName + "_"
						+ new Random().nextInt(1000) + "." + fileExt;
				File uploadedFile = new File(savePath, newFileName);
				try {
					FileCopyUtils.copy(file.getBytes(), uploadedFile);
				} catch (Exception e) {
					request.setAttribute("status", "err");
					request.setAttribute("msg", "上传文件失败 错误代码002");
					return msgPag;
				}
				String visitPath = saveUrl + newFileName;
				log.info("上传一个文件：" + newFileName);

				visitPaths.append(visitPath).append(";");
			}
		}
		// 获取回调函数
		String callBack = request.getParameter("callBack");
		String inputId = request.getParameter("inputId");
		request.setAttribute("status", "ok");
		request.setAttribute("callBack", callBack);
		request.setAttribute("inputId", inputId);
		request.setAttribute("url",
				visitPaths.substring(0, visitPaths.length() - 1));

		return msgPag;
	}

	/**
	 * 检查文件名，过滤特殊字符
	 */
	private String getSensitive(String globWords) {

		String sensitive = "";
		Pattern pattern = Pattern.compile("([[a-zA-Z0-9]{}]{1})");
		Matcher matcher = pattern.matcher(globWords);
		while (matcher.find()) {
			sensitive += matcher.group();
		}
		if (sensitive == "" || sensitive.length() < 3) {
			sensitive = StringUtils.getRandomString(8);
		}
		return sensitive;
	}
}